/**
 * UserInterface.java
 * Created on Feb 17, 2011, 1:07:29 PM
 */

package cs342.project1.mathNotebook.gui;

import cs342.project1.mathNotebook.data.*;
import cs342.project1.mathNotebook.notebook.NotebookEntry;
import cs342.project1.mathNotebook.notebook.NotebookEntryListModel;
import cs342.project1.mathNotebook.notebook.SlopeTable;

import java.awt.Desktop;
import java.awt.IllegalComponentStateException;
import java.io.*;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.text.DecimalFormat;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import java.sql.*;
import java.util.Random;

/**
 * Advanced User Interface for displaying graphs of formula's finding tangents and manipulating expressions.
 * @author Mack Butzen
 * @author Jared Schlicht
 * @author Josh Oberle
 * @author Dexter Hoban
 * @author Brad Hanlon
 */
public class UserInterface extends javax.swing.JFrame {

    //Serves as the model for the list of notebook entries displayed to the user.
    private List<NotebookEntry> notebookEntries;
    
    // View Model for the GUI's list of notebook entries
    private NotebookEntryListModel notebookEntriesListModel;
    private SlopeTable slopeTable;
    private NotebookEntry ne;
    private String input;
    private String currentFilename;
    private int userID;
    
    /** Creates new form UserInterface
     * @author NetBeans
     */
    public UserInterface(int userID) {
        this.userID = userID;
        this.notebookEntries = new ArrayList<NotebookEntry>();
        initComponents();
    }
    
    private DownloadScreen download;
    private PermissionsScreen permissions;

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
	 * Well, I modified it anyway.  - @author oberlj11
	 * @author NetBeans
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        
        this.setLocation(200, 200);

        listPnl = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        notebookEntryJList = new javax.swing.JList();
        newExpBtn = new javax.swing.JButton();
        removeExpBtn = new javax.swing.JButton();
        viewPnl = new javax.swing.JPanel();
        formulaLbl = new javax.swing.JLabel();
        formulaTxt = new javax.swing.JTextField();
        minXLbl = new javax.swing.JLabel();
        lblDimensions = new javax.swing.JLabel();
        maxXLbl = new javax.swing.JLabel();
        minYLbl = new javax.swing.JLabel();
        maxYLbl = new javax.swing.JLabel();
        minXTxt = new javax.swing.JTextField();
        minYTxt = new javax.swing.JTextField();
        maxYTxt = new javax.swing.JTextField();
        maxXTxt = new javax.swing.JTextField();
        areaLbl = new javax.swing.JLabel();
        areaTxt = new javax.swing.JLabel();
        tangentLbl = new javax.swing.JLabel();
        slopeSbr = new javax.swing.JScrollPane();
        slopeTbl = new javax.swing.JTable();
        slopeBtn = new javax.swing.JButton();
        graphMaxY = new javax.swing.JLabel();
        graphMinY = new javax.swing.JLabel();
        graphMinX = new javax.swing.JLabel();
        graphMaxX = new javax.swing.JLabel();
        graph1 = new cs342.project1.mathNotebook.gui.Graph();
        drawBtn = new javax.swing.JButton();
        removeSlopeBtn = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        newMenuItem = new javax.swing.JMenuItem();
        openMenuItem = new javax.swing.JMenuItem();
        saveMenuItem = new javax.swing.JMenuItem();
        saveAsMenuItem = new javax.swing.JMenuItem();
		saveCompressedMenuItem = new javax.swing.JMenuItem();
		saveEncryptedMenuItem = new javax.swing.JMenuItem();
		uploadMenuItem = new javax.swing.JMenuItem();
		downloadMenuItem = new javax.swing.JMenuItem();
        exitMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        aboutMenuItem = new javax.swing.JMenuItem();
        aboutNewMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Math Notebook: Network Edition - Brad, Dexter, Josh");

        notebookEntryJList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                notebookEntryJListMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(notebookEntryJList);

        newExpBtn.setText("New Expression");
        newExpBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newExpBtnActionPerformed(evt);
            }
        });

        removeExpBtn.setText("Remove Expression");
        removeExpBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeExpBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout listPnlLayout = new javax.swing.GroupLayout(listPnl);
        listPnl.setLayout(listPnlLayout);
        listPnlLayout.setHorizontalGroup(
            listPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(listPnlLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(listPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(newExpBtn, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
                    .addComponent(removeExpBtn))
                .addContainerGap())
        );
        listPnlLayout.setVerticalGroup(
            listPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, listPnlLayout.createSequentialGroup()
                .addContainerGap(42, Short.MAX_VALUE)
                .addComponent(newExpBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 313, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(removeExpBtn)
                .addGap(67, 67, 67))
        );

        formulaLbl.setText("Formula:");

        formulaTxt.setEditable(false);

        minXLbl.setText("Min X");

        lblDimensions.setText("Graph Dimensions:");

        maxXLbl.setText("Max X");

        minYLbl.setText("Min Y");

        maxYLbl.setText("Max Y");

        areaLbl.setText("Area:");

        areaTxt.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        tangentLbl.setText("Tangents Calculations:");

        slopeTbl.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "X", "Slope"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        slopeSbr.setViewportView(slopeTbl);

        slopeBtn.setFont(new java.awt.Font("Dialog", 1, 10));
        slopeBtn.setText("New Slope");
        slopeBtn.setMaximumSize(new java.awt.Dimension(50, 23));
        slopeBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                slopeBtnActionPerformed(evt);
            }
        });

        graphMaxY.setText("5.0");

        graphMinY.setText("-5.0");

        graphMinX.setText("-5.0");

        graphMaxX.setText("5.0");

        javax.swing.GroupLayout graph1Layout = new javax.swing.GroupLayout(graph1);
        graph1.setLayout(graph1Layout);
        graph1Layout.setHorizontalGroup(
            graph1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 471, Short.MAX_VALUE)
        );
        graph1Layout.setVerticalGroup(
            graph1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 166, Short.MAX_VALUE)
        );

        drawBtn.setText("Draw");
        drawBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                drawBtnActionPerformed(evt);
            }
        });

        removeSlopeBtn.setFont(new java.awt.Font("Dialog", 1, 10));
        removeSlopeBtn.setText("Remove Slope");
        removeSlopeBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeSlopeBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout viewPnlLayout = new javax.swing.GroupLayout(viewPnl);
        viewPnl.setLayout(viewPnlLayout);
        viewPnlLayout.setHorizontalGroup(
            viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(viewPnlLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(viewPnlLayout.createSequentialGroup()
                        .addComponent(formulaLbl)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(formulaTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 166, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(viewPnlLayout.createSequentialGroup()
                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(viewPnlLayout.createSequentialGroup()
                                .addComponent(lblDimensions)
                                .addGap(107, 107, 107)
                                .addComponent(tangentLbl))
                            .addGroup(viewPnlLayout.createSequentialGroup()
                                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(viewPnlLayout.createSequentialGroup()
                                        .addGap(12, 12, 12)
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(minXLbl)
                                            .addComponent(minYLbl)))
                                    .addComponent(areaLbl))
                                .addGap(18, 18, 18)
                                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(viewPnlLayout.createSequentialGroup()
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(minXTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(minYTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addGroup(viewPnlLayout.createSequentialGroup()
                                                .addComponent(maxXLbl)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(maxXTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
                                            .addGroup(viewPnlLayout.createSequentialGroup()
                                                .addComponent(maxYLbl)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(maxYTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))))
                                    .addComponent(drawBtn)
                                    .addComponent(areaTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(18, 18, 18)
                                .addComponent(slopeSbr, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(12, 12, 12)
                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(slopeBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(removeSlopeBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(viewPnlLayout.createSequentialGroup()
                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(graphMaxY)
                            .addComponent(graphMinY, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(viewPnlLayout.createSequentialGroup()
                                .addComponent(graphMinX)
                                .addGap(426, 426, 426)
                                .addComponent(graphMaxX, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(graph1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(63, Short.MAX_VALUE))
        );
        viewPnlLayout.setVerticalGroup(
            viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(viewPnlLayout.createSequentialGroup()
                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(formulaLbl)
                    .addComponent(formulaTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(viewPnlLayout.createSequentialGroup()
                        .addComponent(graphMaxY)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(graphMinY))
                    .addComponent(graph1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(viewPnlLayout.createSequentialGroup()
                        .addComponent(graphMinX)
                        .addGap(71, 71, 71)
                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(viewPnlLayout.createSequentialGroup()
                                .addGap(6, 6, 6)
                                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(lblDimensions)
                                    .addComponent(tangentLbl))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(viewPnlLayout.createSequentialGroup()
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                            .addComponent(minXLbl)
                                            .addComponent(maxXLbl)
                                            .addComponent(minXTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(maxXTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                            .addComponent(minYLbl)
                                            .addComponent(maxYLbl)
                                            .addComponent(maxYTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(minYTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addGroup(viewPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(areaLbl)
                                            .addComponent(areaTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addGap(15, 15, 15)
                                        .addComponent(drawBtn))
                                    .addComponent(slopeSbr, 0, 0, Short.MAX_VALUE)))
                            .addGroup(viewPnlLayout.createSequentialGroup()
                                .addGap(24, 24, 24)
                                .addComponent(slopeBtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(removeSlopeBtn))))
                    .addComponent(graphMaxX, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(21, 21, 21))
        );

        fileMenu.setText("File");

        newMenuItem.setText("New");
        newMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(newMenuItem);

        openMenuItem.setText("Open");
        openMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(openMenuItem);

        saveMenuItem.setText("Save");
        saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveMenuItem);

        saveAsMenuItem.setText("Save As ...");
        saveAsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveAsMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveAsMenuItem);
		
	saveCompressedMenuItem.setText("Save As (Compressed)");
        saveCompressedMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveCompressedMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveCompressedMenuItem);
		
	saveEncryptedMenuItem.setText("Save As (Compressed and Encrypted)");
        saveEncryptedMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveEncryptedMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveEncryptedMenuItem);

	uploadMenuItem.setText("Upload");
        uploadMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            		try{
            		    uploadMenuItemActionPerformed(evt);
            		}
            		catch (IllegalComponentStateException ex){} 
            		catch (FileNotFoundException e) {} 
            		catch (SQLException e) {} 
                catch (IOException e) {}
            }
        });
        fileMenu.add(uploadMenuItem);

	downloadMenuItem.setText("Download");
        downloadMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downloadMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(downloadMenuItem);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText("Help");

        aboutMenuItem.setText("About");
        aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutMenuItem);
        aboutNewMenuItem.setText("New Features");
        aboutNewMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutNewMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutNewMenuItem);
        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(listPnl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(24, 24, 24)
                .addComponent(viewPnl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(24, 24, 24)
                .addComponent(viewPnl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addComponent(listPnl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }

    /**
     * Closes form.
     * @author Mack Butzen
     */
    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        System.exit(0);
    }
    
    /**
     * Calculates slope at a particular x value and fills table with slope
     * @Author Mack Butzen
     * @param x value (from InputDialog)
     */
    private void slopeBtnActionPerformed(java.awt.event.ActionEvent evt) {

        try {
            Double xCord;
            String slope = JOptionPane.showInputDialog("Please enter an 'x' value");
            xCord = Double.parseDouble(slope);

            ne.tangentPoints.add(xCord);
            
            slopeTable = new SlopeTable(ne);
            slopeTbl.setModel(slopeTable);
            slopeTbl.getColumnModel().getColumn(0).setHeaderValue("X");
            slopeTbl.getColumnModel().getColumn(1).setHeaderValue("Slope");
            slopeTbl.repaint();
            graph1.drawGraph(ne);
        }catch (Exception e){
            JOptionPane.showMessageDialog(null,"Slope not valid");
        }
    }

    /**
     * Takes a new expression, draws the expression on graph and adds expression to expression list.
     *  @Author Mack Butzen
     *  @param espression (from InputDialog)
     */
    private void newExpBtnActionPerformed(java.awt.event.ActionEvent evt) {
        try{    
            	ne = new NotebookEntry();
            input = JOptionPane.showInputDialog(null, "Please enter an expression");
    
            Parser p = new  Parser();
            
            ne.function = p.getExpression(input);
        
            ne.minXCoordinate = -5.0;
            ne.maxXCoordinate = 5.0;
            ne.minYCoordinate = -5.0;
            ne.maxYCoordinate = 5.0;
            ne.functionString = input;
    
            //set graph hash marks
            graphMinX.setText(ne.minXCoordinate + "");
            graphMaxX.setText(ne.maxXCoordinate + "");
            graphMinY.setText(ne.minYCoordinate + "");
            graphMaxY.setText(ne.maxYCoordinate + "");
    
            //set graph size text boxes
            minXTxt.setText(ne.minXCoordinate + "");
            maxXTxt.setText(ne.maxXCoordinate + "");
            minYTxt.setText(ne.minYCoordinate + "");
            maxYTxt.setText(ne.maxYCoordinate + "");

            notebookEntries.add(ne);
            
            formulaTxt.setText(input);
            graph1.drawGraph(ne);
            
            slopeTable = new SlopeTable(ne);
            slopeTbl.setModel(slopeTable);
            slopeTbl.repaint();
    
            //Get and set area.
            areaTxt.setText(roundTwoDecimals(ne.calculateArea()) + "");
            
            notebookEntriesListModel = new NotebookEntryListModel(notebookEntries);
            notebookEntryJList.setModel(notebookEntriesListModel);
            notebookEntryJList.repaint();
            
            notebookEntryJList.setSelectedIndex(notebookEntries.size()-1);
            notebookEntryJList.repaint();
            
        }catch(Exception e){
            JOptionPane.showMessageDialog(null,"Expression not valid");
        }
    }

    private double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
        if ( new Double(d).toString().equals("NaN"))
        	return d;
        return Double.valueOf(twoDForm.format(d));
    }

    /**
     * When an expression is selected in the ExpressionList, load the expression as the current exp.
     * @Author Mack Butzen
     */
    private void notebookEntryJListMouseClicked(java.awt.event.MouseEvent evt) {
        if(this.notebookEntries.size() == 0) {
            return;
        }
    	
    	    formulaTxt.setText(((NotebookEntry)(notebookEntryJList.getSelectedValue())).functionString);
        ne = (NotebookEntry)(notebookEntryJList.getSelectedValue());
        
        ne.minXCoordinate = -5.0;
        ne.maxXCoordinate = 5.0;
        ne.minYCoordinate = -5.0;
        ne.maxYCoordinate = 5.0;
        
        //set graph hash marks
        graphMinX.setText(ne.minXCoordinate + "");
        graphMaxX.setText(ne.maxXCoordinate + "");
        graphMinY.setText(ne.minYCoordinate + "");
        graphMaxY.setText(ne.maxYCoordinate + "");

        //set graph size text boxes
        minXTxt.setText(ne.minXCoordinate + "");
        maxXTxt.setText(ne.maxXCoordinate + "");
        minYTxt.setText(ne.minYCoordinate + "");
        maxYTxt.setText(ne.maxYCoordinate + "");
        
        areaTxt.setText(roundTwoDecimals(ne.calculateArea()) + "");
        
        graph1.drawGraph(ne);
        graph1.repaint();
        
        slopeTable = new SlopeTable((NotebookEntry)(notebookEntryJList.getSelectedValue()));
        slopeTbl.setModel(slopeTable);
        slopeTbl.getColumnModel().getColumn(0).setHeaderValue("X");
        slopeTbl.getColumnModel().getColumn(1).setHeaderValue("Slope");
        slopeTbl.repaint();
    }
    
    /**
     * Redraws graph with new display parameters
     * @Author Mack Butzen
     */
    private void drawBtnActionPerformed(java.awt.event.ActionEvent evt) {
        double minx, miny, maxx, maxy;

        try {

            minx = Double.parseDouble(minXTxt.getText());
            maxx = Double.parseDouble(maxXTxt.getText());
            miny = Double.parseDouble(minYTxt.getText());
            maxy = Double.parseDouble(maxYTxt.getText());

            if (minx > maxx || miny > maxy) {
                throw new Exception();
            }
            ne.minXCoordinate = Double.parseDouble(minXTxt.getText());
            ne.maxXCoordinate = Double.parseDouble(maxXTxt.getText());
            ne.minYCoordinate = Double.parseDouble(minYTxt.getText());
            ne.maxYCoordinate = Double.parseDouble(maxYTxt.getText());

            //set graph hash marks
            graphMinX.setText(ne.minXCoordinate + "");
            graphMaxX.setText(ne.maxXCoordinate + "");
            graphMinY.setText(ne.minYCoordinate + "");
            graphMaxY.setText(ne.maxYCoordinate + "");

        //recalculate area
        areaTxt.setText(roundTwoDecimals(ne.calculateArea()) + "");

        //redraw graph
        graph1.drawGraph(ne);
        
        }catch(Exception e){
            JOptionPane.showMessageDialog(null,"Graph bounds not valid");
        }
    }
    
    /**
     * Calls save as if the current notebook has not already saved. If it has
     * been saved before, simply save it to the current file.
     * @author Jared Schlicht
     * @param evt
     */
    private void saveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        	if (this.currentFilename != null) {
        		this.saveFile();
        	} else {
        		this.saveFileAs();
        	}
    }
    
    /**
     * Creates a new notebook
     * @author Jared Schlicht
     * @author Dexter Hoban
     * @param evt
     */
    private void newMenuItemActionPerformed(java.awt.event.ActionEvent evt) {

        try {
            Object[] options = {"Yes", "Cancel" };
            int result = JOptionPane.showOptionDialog(this, "Are you sure you want to discard any changes of the file you are currently working on?", "ATTENTION", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
            if (result == JOptionPane.NO_OPTION) {
                // Do nothing - User cancelled.
            }
            else if (result == JOptionPane.YES_OPTION) {
                clearGUI();
            }
        }
        catch(Exception e) {
            //Damn you netbeans
        }
    }
    
    /**
     * Clears data from GUI and starts fresh.
     * @author Jared Schlicht
     * @author Dexter Hoban
     */
    private void clearGUI() {
        
        try {
            this.notebookEntries.clear();
            this.currentFilename = null;
            this.notebookEntryJList.repaint();
            this.areaTxt.setText("");
            this.formulaTxt.setText("");
            
            this.graphMaxX.setText("");
            this.maxXTxt.setText("");
            
            this.graphMaxY.setText("");
            this.maxYTxt.setText("");
            
            this.graphMinX.setText("");
            this.minXTxt.setText("");
            
            this.graphMinY.setText("");
            this.minYTxt.setText("");
            
            this.ne = null;
            this.graph1.drawGraph(this.ne);
    
            slopeTbl.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {
                    {null, null},
                    {null, null},
                    {null, null},
                    {null, null}
                },
                new String [] {
                    "X", "Slope"
                }
            ) {
                Class[] types = new Class [] {
                    java.lang.String.class, java.lang.String.class
                };
    
                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }
            });
            slopeTbl.repaint();
        }
        catch (Exception e) {
            // Catch Netbeans GUI Exception - Do Nothing
        }
    } // End of clearGUI method.
    
    /**
     * Opens all possible data formats.
     * 
     * @Author Mack Butzen
     * @author Josh Oberle
     * @Author Dexter Hoban
	 * modified 3/6/11
	 * added file filters
	 * modified 3/7/11
	 * added way to save open GZip files.
	 * modified 3/29/11
	 * Added popup confirmation
     */
    private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
       
        try {
            Object[] options = {"Yes", "Cancel" };
            int result = JOptionPane.showOptionDialog(this, "Are you sure you want to open a new file and discard what you are currently working on?", "ATTENTION", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
            if (result == JOptionPane.NO_OPTION) {
                // Do nothing - User cancelled.
            }
            else if (result == JOptionPane.YES_OPTION) {
                JFileChooser fileChooser = new JFileChooser();
        		    fileChooser.setAcceptAllFileFilterUsed(false);
        		    fileChooser.addChoosableFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("XML Files","xml"));
                fileChooser.addChoosableFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("GZip Files","gz"));
                fileChooser.addChoosableFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("DATA Files","dat"));
                fileChooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("Valid File Types","xml","gz","dat"));
        		
                int openResult = fileChooser.showOpenDialog(this);
                if (openResult != JFileChooser.APPROVE_OPTION) {
                    return;
                }

                File file = fileChooser.getSelectedFile();
                this.currentFilename = file.getAbsolutePath();
                openFile(currentFilename);
            }
        }
        catch (Exception e) {
            // Catch netbeans GUI exception - Do Nothing.
        }
    }

    private void openFile(String file){

		if (file.endsWith(".xml")){

			XMLNotebook xml = new XMLNotebook(file);
			notebookEntries = xml.loadNotebook(file);
		} 
		
		// Opens Local Encrypted File
		else if (file.endsWith(".dat")) {
		    
		    // Prompt user for decryption password
            String password = JOptionPane.showInputDialog(this, "Please insert key for decryption:");

            // Decrypt file - delete .dat file.
            String decryptedFilename = file.substring(0, file.length()-4);
            Encryption.decrypt(file, password, decryptedFilename+".gz");
            
            new File(file).delete();
            file = decryptedFilename+".gz";
            
            //After decryption - Unzip and create XMLNotebook - get rid of .dat
            GZip.unzip(file);
            String tempPath = file.substring(0, file.length() - 3);
            NotebookReader reader = new XMLNotebookRepositoryFactory(tempPath).createReader();
            notebookEntries = reader.getAll();
            reader.close();
            File dFile = new File(tempPath);
            dFile.delete();
        } 
		
		// Opens Local Zipped File
		else if (file.endsWith(".gz")){
			GZip.unzip(file);
			String tempPath = file.substring(0,file.length() - 3);
			NotebookReader reader = new XMLNotebookRepositoryFactory(tempPath).createReader();
			notebookEntries = reader.getAll();
			reader.close();
			//System.out.println(tempPath);
			File dFile = new File(tempPath);
			dFile.delete();
		}
		
        notebookEntriesListModel = new NotebookEntryListModel(notebookEntries);
        notebookEntryJList.setModel(notebookEntriesListModel);
        notebookEntryJList.repaint();
        
        if (this.notebookEntries.size() == 0) {
     	   return;
        }
     	
        notebookEntryJList.setSelectedIndex(0);
     	formulaTxt.setText(((NotebookEntry)(notebookEntryJList.getSelectedValue())).functionString);
     	ne = (NotebookEntry)(notebookEntryJList.getSelectedValue());
    
     	ne.minXCoordinate = -5.0;
     	ne.maxXCoordinate = 5.0;
     	ne.minYCoordinate = -5.0;
     	ne.maxYCoordinate = 5.0;
 
     	//set graph hash marks
     	graphMinX.setText(ne.minXCoordinate + "");
     	graphMaxX.setText(ne.maxXCoordinate + "");
     	graphMinY.setText(ne.minYCoordinate + "");
     	graphMaxY.setText(ne.maxYCoordinate + "");

     	//set graph size text boxes
     	minXTxt.setText(ne.minXCoordinate + "");
     	maxXTxt.setText(ne.maxXCoordinate + "");
     	minYTxt.setText(ne.minYCoordinate + "");
     	maxYTxt.setText(ne.maxYCoordinate + "");
 
     	areaTxt.setText(roundTwoDecimals(ne.calculateArea()) + "");
 
     	graph1.drawGraph(ne);
     	graph1.repaint();
 
     	slopeTable = new SlopeTable((NotebookEntry)(notebookEntryJList.getSelectedValue()));
     	slopeTbl.setModel(slopeTable);
     	slopeTbl.getColumnModel().getColumn(0).setHeaderValue("X");
     	slopeTbl.getColumnModel().getColumn(1).setHeaderValue("Slope");
     	slopeTbl.repaint();
    }
    
    /**
     * Save current expression list to XML
     * @author Mack Butzen
     */
    private void saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
    	    this.saveFileAs();
    }

    /**
     * Shows the save as file dialog and writes the XML to the selected file
     * @author Jared Schlicht
	 * modified 3/6/11
	 * changed so that it has an XML filter. Joshua Oberle
     */
    private void saveFileAs() {
        JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("XML Files","xml"));

        int saveResult = fileChooser.showSaveDialog(this);
        if (saveResult != JFileChooser.APPROVE_OPTION) {
            return;
        }

        File file = fileChooser.getSelectedFile();
        this.currentFilename = file.getAbsolutePath();
		if(!currentFilename.endsWith(".xml")) {
			currentFilename += ".xml";
		}
        
        this.saveFile();
    }

    /**
     * Saves the current notebook entry to XML. The current filename must have
     * been set previously by the Save As method.
     * @author Jared Schlicht
     * @author Dexter Hoban
     */
    private void saveFile() {
		//reverted
            XMLNotebook xml = new XMLNotebook(this.currentFilename);
            xml.saveNotebook(notebookEntriesListModel.notebookEntries);
    
    }
    
    /**
     * Removes expression from expression list
     * @author Mack Butzen
     * @param selected expression
     */
    private void removeExpBtnActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            //Reset graph view
            ne.minXCoordinate = -5.0;
            ne.maxXCoordinate = 5.0;
            ne.minYCoordinate = -5.0;
            ne.maxYCoordinate = 5.0;
            ne.functionString = input;
    
            //set graph hash marks
            graphMinX.setText(ne.minXCoordinate + "");
            graphMaxX.setText(ne.maxXCoordinate + "");
            graphMinY.setText(ne.minYCoordinate + "");
            graphMaxY.setText(ne.maxYCoordinate + "");
    
            //set graph size text boxes
            minXTxt.setText(ne.minXCoordinate + "");
            maxXTxt.setText(ne.maxXCoordinate + "");
            minYTxt.setText(ne.minYCoordinate + "");
            maxYTxt.setText(ne.maxYCoordinate + "");
    
            notebookEntriesListModel = new NotebookEntryListModel(notebookEntries);
    
            ne = new NotebookEntry();
            graph1.drawGraph(ne);
            areaTxt.setText("");
            formulaTxt.setText("");
    
            slopeTable = new SlopeTable(ne);
            slopeTbl.setModel(slopeTable);
            slopeTbl.getColumnModel().getColumn(0).setHeaderValue("X");
            slopeTbl.getColumnModel().getColumn(1).setHeaderValue("Slope");
            slopeTbl.repaint();
    
            int index = notebookEntryJList.getSelectedIndex();
            notebookEntries.remove(index);
            notebookEntryJList.setModel(notebookEntriesListModel);
            notebookEntryJList.repaint();
            graph1.repaint();
        }
        catch(Exception e) {}
    }

    private void removeSlopeBtnActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            int index = notebookEntryJList.getSelectedIndex();
            notebookEntries.get(index).tangentPoints.remove(slopeTbl.getSelectedRow());
            slopeTable = new SlopeTable((NotebookEntry)(notebookEntryJList.getSelectedValue()));
            slopeTbl.setModel(slopeTable);
            slopeTbl.getColumnModel().getColumn(0).setHeaderValue("X");
            slopeTbl.getColumnModel().getColumn(1).setHeaderValue("Slope");
            slopeTbl.repaint();
            graph1.repaint();
        }
        catch(Exception e) {}
    }

    private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
    	File file = new File("docs/UserManual.pdf");
        try {
			Desktop.getDesktop().open(file);
		} catch (IOException e) {}
    }
    
    private void aboutNewMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        File file = new File("docs/NewFeatures.pdf");
        try {
            Desktop.getDesktop().open(file);
        } catch (IOException e) {}
    }
    
	 /**
     * Shows the save file dialog for compressed files.
     * @author Joshua Oberle
     * @param evt
     */
	
	private void saveCompressedMenuItemActionPerformed(java.awt.event.ActionEvent evt){
        JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("GZip Files","gz"));

        int saveResult = fileChooser.showSaveDialog(this);
        if (saveResult != JFileChooser.APPROVE_OPTION) {
            return;
        }

        File file = fileChooser.getSelectedFile();
        this.currentFilename = file.getAbsolutePath();
		if(!currentFilename.endsWith(".gz"))
			currentFilename += ".gz";
        
        this.saveFileCompressed();
	}
	
	/**
     * Shows the save file dialog for compressed and encrypted files.
     * @author Joshua Oberle
     * @param evt
     */
	
	private void saveEncryptedMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("DATA Files","dat"));

        int saveResult = fileChooser.showSaveDialog(this);
        if (saveResult != JFileChooser.APPROVE_OPTION) {
            return;
        }
        File file = fileChooser.getSelectedFile();
        this.currentFilename = file.getAbsolutePath();
		if (!currentFilename.endsWith(".dat")) {
			currentFilename += ".dat";
		}
        this.saveFileCompressedAndEncrypted();
	}
	
	/**
	* Saves Files to the gz format locally.
	* @author Joshua Oberle
	*/
	private void saveFileCompressed() {
		currentFilename += ".xml";
		this.saveFile();
		GZip.zip(currentFilename);
		File file = new File(currentFilename);
		file.delete();
		currentFilename = currentFilename.substring(0,currentFilename.length() - 4);
	}
	
   /**
    * Compresses file then saves file to the .dat format locally.
    * @author Dexter Hoban
    * Modified by @author Brad Hanlon, Josh Oberle
    */
    private void saveFileCompressedAndEncrypted() {
        // Compress file.
        currentFilename = currentFilename.substring(0, currentFilename.length() - 4);
        currentFilename += ".gz";
        saveFileCompressed();
        
        // Encryption of compressed file.
        String password = JOptionPane.showInputDialog(this, "Please enter encryption password:");
        String outputFilename = currentFilename.substring(0, currentFilename.length()-3);
        Encryption.encrypt(currentFilename, password, outputFilename+".dat");
        File file = new File(currentFilename);
        file.delete();
        currentFilename = outputFilename+".dat";
    }

    /**
     * Saves Files to the database server.
     * @author Joshua Oberle
     * Modified by @author Brad Hanlon, Dexter Hoban
     * @param evt
     */
	private void uploadMenuItemActionPerformed(java.awt.event.ActionEvent evt) throws SQLException, FileNotFoundException, IOException{

    	    MathDatabase mdb = new MathDatabase();
    		ResultSet rs;
    		File blobFile = null;
    		mdb.open();
    		mdb.getStatement().executeQuery("SELECT pubKey FROM Users WHERE userID = " + '"' + userID + '"');
    		rs = mdb.getStatement().getResultSet();
    		if(rs.next()){
    			blobFile = new File("pubkey.dat");
    			FileOutputStream  outStream  = new FileOutputStream(blobFile);
    			InputStream       inStream   = rs.getBinaryStream(1);
    
    			int     length  = -1;
    			int     size    = inStream.available();
    			byte[]  buffer  = new byte[size];
    						 
    			while ((length = inStream.read(buffer)) != -1)
    			{
    				outStream.write(buffer, 0, length);
    				outStream.flush();
    			}
    			inStream.close();
    			outStream.close();
    		}
    		currentFilename = JOptionPane.showInputDialog(this, "Please enter filename");
    		if (currentFilename != null) {
        		currentFilename += ".gz";
        		saveFileCompressed();
        		String pass = generateRandomDESPassword();
        		String encryptedFilename = currentFilename.substring(0, currentFilename.length()-3);
        		Encryption.encrypt(currentFilename,pass,encryptedFilename+".dat");
                new File(currentFilename).delete();
                currentFilename = encryptedFilename+".dat";
        
        		mdb.getStatement().executeQuery("SELECT * FROM Files WHERE filename = " + '"' + currentFilename + '"');
        		rs = mdb.getStatement().getResultSet();
        		
        		if(rs.next()){
    				int answer = JOptionPane.showConfirmDialog(null,"You are about to overwright this file", "Warning", JOptionPane.OK_CANCEL_OPTION);
    				if(answer == JOptionPane.OK_OPTION){
    					PreparedStatement ps = mdb.createPreparedStatement("UPDATE Files SET fileContent = ?, lastModID = ?, isCheckedOut = ?, encryptedDESKey = ? WHERE filename = " + '"' + currentFilename + '"');
    					
    					ps.setBinaryStream(1,new FileInputStream(currentFilename), (int) new File(currentFilename).length());
    					ps.setInt(2,userID);
    					int response = JOptionPane.showConfirmDialog(null,"Would you like to check out the file you just uploaded?", "Warning", JOptionPane.YES_NO_OPTION);
    					if(response == JOptionPane.YES_OPTION)
    						ps.setBoolean(3,true);
    					else
    						ps.setBoolean(3, false);
    					Encryption.RSAencrypt(pass, blobFile.getAbsolutePath(), "output");
    					File outFile = new File("output");
    
    					ps.setBinaryStream(4, new FileInputStream("output"), (int) outFile.length());
    					ps.executeUpdate();
    					outFile.delete();
    					mdb.commit();
    					
    					mdb.getStatement().executeQuery("SELECT fileID FROM Files WHERE filename = " + '"' + currentFilename + '"');
                		rs = mdb.getStatement().getResultSet();
                		rs.first();
                		int fileID = rs.getInt(1);
                		
                		// Set Permissions
                		permissions = new PermissionsScreen(fileID, "modify");
                		permissions.getAcceptButton().addActionListener(new java.awt.event.ActionListener() {
                            public void actionPerformed(java.awt.event.ActionEvent evt) {
                                permissionsScreenActionPerformed(evt);
                            }
                        });
    				}
        		}//if it is check out, if it is not check out
        		else{	
        			//getEncrypted and compress	
        			PreparedStatement ps = mdb.createPreparedStatement("INSERT INTO Files(filename, fileContent, creatorID, lastModID, isCheckedOut,encryptedDESKey) VALUES(?,?,?,?,?,?)");
        
        			
        			ps.setString(1,currentFilename);
        			ps.setBinaryStream(2,new FileInputStream(currentFilename), (int) new File(currentFilename).length());
        			ps.setInt(3, userID);
        			ps.setInt(4, userID);
        			int answer = JOptionPane.showConfirmDialog(null,"Would you like to check out the file you just created?", "Warning", JOptionPane.YES_NO_OPTION);
        			if(answer == JOptionPane.YES_OPTION)
        				ps.setBoolean(5,true);
        			else
        				ps.setBoolean(5, false);
        
        			Encryption.RSAencrypt(pass, blobFile.getAbsolutePath(), "output");
        			File outFile = new File("output");
        
        			ps.setBinaryStream(6, new FileInputStream("output"), (int) outFile.length());
        			ps.executeUpdate();
        			mdb.commit();
        			
        			mdb.getStatement().executeQuery("SELECT fileID FROM Files WHERE filename = " + '"' + currentFilename + '"');
            		rs = mdb.getStatement().getResultSet();
            		rs.first();
            		int fileID = rs.getInt(1);
            		
            		// Set Permissions
            		permissions = new PermissionsScreen(fileID, "set");
            		permissions.getAcceptButton().addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                            permissionsScreenActionPerformed(evt);
                        }
                    });
        			        			
        		}//if it exists, if it does not exist
        		    		
        		
        		mdb.close();
        		}
	}//uploadMenuItemActionPerformed(ActionEvent)

	private void permissionsScreenActionPerformed(java.awt.event.ActionEvent evt){
		permissions.setPermissions();
		permissions.dispose();
	}
	
    /**
     * Generates random DES keys.
     * @author Joshua Oberle
     */
	private String generateRandomDESPassword(){

		byte number;
		String returnString = "";
		for(int i = 0; i < 8; i++){
			number = (byte)(Math.random() * 92);
			number += 33;
			returnString += (char) number;
		}
		return returnString;
	}
	
    /**
     * Action for Download.
     * @author Brad Hanlon
     * @param evt
     */
	private void downloadMenuItemActionPerformed(java.awt.event.ActionEvent evt){
		download = new DownloadScreen(userID);
		download.getDownloadButton().addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downloadScreenActionPerformed(evt);
            }
        });
	}

    /**
     * Prompts user with list of available files to download.
     * @author Brad Hanlon
     * @param evt
     */
	private void downloadScreenActionPerformed(java.awt.event.ActionEvent evt){
		
		try{
		    File file = download.getSelectedFile();
		    if(file == null)
		    	throw new Exception("File is null");
		    
			File publicKey = download.getPublicKey();
			if(publicKey == null)
				throw new Exception("Public key is null");
			
			File encryptedDESkey = download.getDESKey();
			if(encryptedDESkey == null)
				throw new Exception("DES key is null");
			
			String currentFilename = file.getAbsolutePath();
			
	        String desFilename = encryptedDESkey.getAbsolutePath();		
	        String pubFilename = publicKey.getAbsolutePath();
	        
	        String deskey = Encryption.RSAdecrypt(desFilename, pubFilename);
	        String decryptedFilename = currentFilename.substring(0, currentFilename.length()-4);
	        Encryption.decrypt(currentFilename, deskey, decryptedFilename+".gz");
            
            new File(currentFilename).delete();
            currentFilename = decryptedFilename+".gz";            
            
            download.dispose();
            openFile(currentFilename);
		}
		catch(Exception e){
		}
	}
	
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JMenuItem aboutNewMenuItem;
    private javax.swing.JLabel areaLbl;
    private javax.swing.JLabel areaTxt;
    private javax.swing.JButton drawBtn;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JLabel formulaLbl;
    private javax.swing.JTextField formulaTxt;
    private cs342.project1.mathNotebook.gui.Graph graph1;
    private javax.swing.JLabel graphMaxX;
    private javax.swing.JLabel graphMaxY;
    private javax.swing.JLabel graphMinX;
    private javax.swing.JLabel graphMinY;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lblDimensions;
    private javax.swing.JPanel listPnl;
    private javax.swing.JLabel maxXLbl;
    private javax.swing.JTextField maxXTxt;
    private javax.swing.JLabel maxYLbl;
    private javax.swing.JTextField maxYTxt;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JLabel minXLbl;
    private javax.swing.JTextField minXTxt;
    private javax.swing.JLabel minYLbl;
    private javax.swing.JTextField minYTxt;
    private javax.swing.JButton newExpBtn;
    private javax.swing.JMenuItem newMenuItem;
    private javax.swing.JList notebookEntryJList;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JButton removeExpBtn;
    private javax.swing.JButton removeSlopeBtn;
    private javax.swing.JMenuItem saveAsMenuItem;
    private javax.swing.JMenuItem saveMenuItem;
    private javax.swing.JButton slopeBtn;
    private javax.swing.JScrollPane slopeSbr;
    private javax.swing.JTable slopeTbl;
    private javax.swing.JLabel tangentLbl;
    private javax.swing.JPanel viewPnl;
	private javax.swing.JMenuItem saveCompressedMenuItem;
	private javax.swing.JMenuItem saveEncryptedMenuItem;
	private javax.swing.JMenuItem uploadMenuItem;
	private javax.swing.JMenuItem downloadMenuItem;
    // End of variables declaration//GEN-END:variables

}